package effects;

import loadsave.Memento;
import loadsave.loadsaveobject.Iterator;
import loadsave.loadsaveobject.LoadSaveObject;
import loadsave.loadsaveobject.LoadSaveObjectComposite;
import stat.EntityStatList;
import stat.NonEntityStatList;
import stat.StatList;
import stat.StatType;
import visitors.EffectsVisitor;

/**
 * DEPRECATED
 * 
 * The GainExperienceEffect class is meant to encapsulate
 * an effect that adds experience to an entity.  The class
 * contains the appropriate modifiers to compute the effect.
 * This class is necessary as a target for double dispatch
 * for the Visitor class.
 * 
 * GainExperienceEffect is in charge of computing the value
 * of experience gain from the source stats and provide that
 * to the client.
 * 
 * @author DangMH
 *
 */
public class GainExperienceEffect extends Effect {
	private StatList experienceStats;
	
	/**
	 * Empty constructor
	 */
	public GainExperienceEffect() {
		experienceStats = new NonEntityStatList();
	}
	
	/**
	 * Parameterized Constructor
	 * @param modelName
	 * Name of the modal image
	 * @param statList
	 * Stats for experience influence
	 */
	public GainExperienceEffect( String modelName, StatList statList ) {
		super( modelName );
		this.experienceStats = statList;
	}
	
	/**
	 * Visitor interface
	 */
	public void accept( EffectsVisitor ev ) {
		ev.visitGainExperienceEffect( this );
	}
	
	/**
	 * Computes the delta experience, assumes addStats
	 */
	public StatList computeStats() {
		StatList ret = new NonEntityStatList();
		
		ret.addStat( StatType.EXP, computeExp() );
		
		return ret;
	}
	
	/**
	 * private method to derive the delta experience
	 */
	private int computeExp() {
		int ret = 0;
		
		for( StatType st : getRelevantStats() ) {
			ret += experienceStats.getStat( st );
		}
		
		return ret;
	}

	/**
	 * public mutator for stats
	 */
	public void setStats(StatList statList) {
		experienceStats = statList;		
	}

	@Override
	public Memento getMemento() {
		return new Memento() {

			@Override
			public LoadSaveObject getState() {
				LoadSaveObject lso = GainExperienceEffect.super.getMemento().getState();
				LoadSaveObjectComposite toReturn = new LoadSaveObjectComposite("", "GainExperienceEffect");
				Iterator<LoadSaveObject> i = lso.getIterator();
				for (i.init(); i.hasNext(); i.next()) {
					toReturn.add(i.getCurrKey().getValue(), i.getCurrVal());
				}
				lso = experienceStats.getMemento().getState();
				lso.setName("experienceStats");
				toReturn.add(lso.getName(), lso);
				return toReturn;
			}

			@Override
			public void restoreState(LoadSaveObject lso) {
				GainExperienceEffect.super.getMemento().restoreState(lso);
				experienceStats = new EntityStatList();
				experienceStats.getMemento().restoreState(lso.get("experienceStats"));
			}
			
		};
	}

	@Override
	public GainExperienceEffect clone() {
		StatList expStats = new EntityStatList();
		expStats.addStats(this.experienceStats);
		return new GainExperienceEffect(getName(), expStats);
	}
}
